home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / Mark.C < prev    next >
C/C++ Source or Header  |  1992-05-05  |  5KB  |  259 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Mark.h"
  6.  
  7. #include "Class.h"
  8. #include "OrdColl.h"
  9. #include "Math.h"
  10.  
  11. //---- Mark --------------------------------------------------------------------
  12.  
  13. NewMetaImpl(Mark,Object, (T(pos), T(len), T(state)));
  14.  
  15. Mark::Mark(int p, int l, eMarkState s, eMarkFlags flags)
  16. {
  17.     pos= p;
  18.     len= l;
  19.     state= s;
  20.     if ((flags & eMarkInclStart) == eMarkInclStart)
  21.     SetFlag(eMarkInclStart);
  22.     if ((flags & eMarkFixedSize) == eMarkFixedSize)
  23.     SetFlag(eMarkFixedSize);
  24.     if ((flags & eMarkLocked) == eMarkLocked)
  25.     SetFlag(eMarkLocked);
  26. }
  27.  
  28. Mark::Mark(Mark *m)
  29. {
  30.     pos= m->pos;
  31.     len= m->len;
  32.     state= m->state;
  33. }
  34.  
  35. int Mark::Compare(Object *op)   
  36. {
  37.     return (pos - ((Mark*)op)->pos);
  38. }
  39.  
  40. bool Mark::HasChanged (int start,int l)
  41. {
  42.     return (state != eStateNone || pos != start || len != l);
  43. }
  44.  
  45. OStream &Mark::PrintOn(OStream& s)
  46. {
  47.     Object::PrintOn(s);
  48.     return s << pos SP << len SP << state SP;
  49. }
  50.  
  51. IStream &Mark::ReadFrom(IStream& s)
  52. {
  53.     Object::ReadFrom(s);
  54.     return s >> pos >> len >> Enum(state);
  55. }
  56.  
  57. Object *Mark::deepclone()
  58. {
  59.     if (IsA() == Meta(Mark))
  60.     return new Mark(pos, len, (eMarkState)state);
  61.     return 0;
  62. }
  63.  
  64. void Mark::Cut(int at, int n)
  65. {
  66.     if (at < 0)
  67.     n+= at;
  68.     at= Math::Max(0, at);
  69.  
  70.     // the different cases are shown as: '|' = mark positions '^' deleted range
  71.  
  72.     if (TestFlag(eMarkLocked))
  73.     return;
  74.  
  75.     if (TestFlag(eMarkFixedSize)) {
  76.     // ^ |    |   ^ includes ^ |   ^|
  77.     if (at <= pos && at + n >= pos + len) {
  78.         state= eStateDeleted;
  79.         len= 0;
  80.         pos= at;
  81.     }
  82.     // ^ ^ |    | includes ^  ^|   |
  83.     else if (at + n <= pos) {
  84.         pos-= n;
  85.     }
  86.  
  87.     //    |    |  ^  ^ includes |    |^  ^
  88.     else if (at >= pos + len)
  89.         ;
  90.     // ^ | ^  |,  |  ^ | ^,| ^ ^ | includes |^   ^|
  91.     else
  92.         Error("Cut", "should not occur");
  93.  
  94.     } else {           
  95.     // | ^ ^ | includes |^   ^|
  96.     if (at >= pos && at + n <= pos + len) { // contained
  97.         state= eStateChanged;
  98.         len-= n;
  99.     }
  100.  
  101.     // ^ |    |   ^ includes ^ |   ^|
  102.     else if (at < pos && at + n >= pos + len) {
  103.         state= eStateDeleted;
  104.         len= 0;
  105.         pos= at;
  106.     }
  107.  
  108.     // ^ | ^  |
  109.     else if (at < pos && at + n > pos) {
  110.         len= pos+len - (at +n); 
  111.         pos= at;
  112.         state= eStateChanged;
  113.     }
  114.  
  115.     // |  ^ | ^
  116.     else if (at >= pos && at < pos + len) {
  117.         len= at - pos;
  118.         state= eStateChanged;
  119.     }
  120.  
  121.     // ^ ^ |    | includes ^  ^|   |
  122.     else if (at + n <= pos) 
  123.         pos-= n;
  124.  
  125.     //    |    |  ^  ^ includes |    |^  ^
  126.     else if (at >= pos + len)
  127.         ;
  128.     else    
  129.         Error("Cut", "should not occur");  
  130.     }          
  131. }
  132.  
  133. void Mark::Paste(int at, int n)
  134. {
  135.     n= Math::Max(0, n);
  136.     at= Math::Max(0, at);
  137.  
  138.     if (TestFlag(eMarkLocked))
  139.     return;
  140.     if ((at > pos || (TestFlag(eMarkInclStart) && at == pos)) && at < pos + len){
  141.     state= eStateChanged;
  142.     len += n;
  143.     
  144.     } else if (at < pos || (!TestFlag(eMarkInclStart) && at == pos)) 
  145.     pos += n;
  146. }
  147.     
  148. void Mark::Change(int at, int n)
  149. {
  150.     if (TestFlag(eMarkLocked))
  151.     return;
  152.     if (at < pos && at+n >= pos+len)
  153.     state= eStateChanged;
  154.     else if (at >= pos && at < pos+len)
  155.     state= eStateChanged;
  156.     else if (at+n >= pos && at+n < pos+len)
  157.     state= eStateChanged;
  158. }
  159.  
  160. //---- MarkList ----------------------------------------------------------------
  161.  
  162. NewMetaImpl(MarkList,Object, (TP(marks), TB(doRemove)));
  163.  
  164. MarkList::MarkList(bool remove, SeqCollection *rep)
  165. {   
  166.     doRemove= remove;
  167.     if (rep)
  168.     marks= rep;
  169.     else
  170.     marks= new OrdCollection;
  171. }
  172.  
  173. MarkList::~MarkList()
  174. {   
  175.     if (doRemove)
  176.     marks->FreeAll();
  177.     SafeDelete(marks);
  178. }
  179.  
  180. void MarkList::Add(Mark *m)
  181. {   
  182.     marks->Add(m);
  183. }
  184.  
  185. Mark *MarkList::Remove(Mark *m)
  186. {   
  187.     return (Mark*)marks->Remove(m);
  188. }
  189.  
  190. Mark *MarkList::At(int i)
  191. {
  192.     return (Mark*)marks->At(i);
  193. }
  194.  
  195. Iterator *MarkList::MakeIterator()
  196. {   
  197.     return marks->MakeIterator();
  198. }
  199.  
  200. void MarkList::FreeAll()
  201. {   
  202.     return marks->FreeAll();
  203. }
  204.  
  205. int MarkList::Size()
  206. {   
  207.     return marks->Size();
  208. }
  209.  
  210. void MarkList::Empty()
  211. {   
  212.     return marks->Empty(marks->Size());
  213. }
  214.  
  215. void MarkList::Replace(int from, int to, int sz)
  216. {
  217.     Iter next(marks);
  218.     Mark *m;
  219.     int n= to-from;
  220.     
  221.     while (m= (Mark*)next()) {
  222.     if(from != to) {
  223.         m->Cut(from, n);
  224.         if (doRemove && m->state == eStateDeleted) {
  225.         marks->Remove(m);
  226.         m->FreeAll();
  227.         delete m;
  228.         }
  229.     }
  230.     if (sz)
  231.         m->Paste(from, sz);
  232.     }
  233. }
  234.  
  235. void MarkList::RangeChanged(int at,int n)
  236. {
  237.     Iter next(marks);
  238.     Mark *m;
  239.  
  240.     n= Math::Max(0, n);
  241.     at= Math::Max(0, at);
  242.  
  243.     while (m= (Mark*) next()) 
  244.     m->Change(at, n);
  245. }
  246.  
  247. OStream& MarkList::PrintOn (OStream&s)
  248. {
  249.     Object::PrintOn(s);
  250.     return s << doRemove << marks SP;
  251. }
  252.  
  253. IStream& MarkList::ReadFrom(IStream &s)
  254. {
  255.     Object::ReadFrom(s);
  256.     return s >> Bool(doRemove) >> marks;
  257. }
  258.  
  259.